//+------------------------------------------------------------------+
//|                                         TrailingParabolicSAR.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert/ExpertTrailing.h>  // 移动止损基类（提供止损框架）

// wizard description start（MQL5 策略向导描述）
//+------------------------------------------------------------------+
//| 类功能描述                                                       |
//| Title=基于抛物线转向指标（Parabolic SAR）的移动止损               |
//| Type=Trailing                                                    |
//| Name=ParabolicSAR                                                |
//| Class=CTrailingPSAR                                              |
//| Page=                                                            |
//| Parameter=Step,double,0.02,步长（加速因子增量，控制SAR跟随速度）    |
//| Parameter=Maximum,double,0.2,最大值（加速因子上限，避免SAR过于敏感） |
//+------------------------------------------------------------------+
// wizard description end

//+------------------------------------------------------------------+
//| CTrailingPSAR 类：基于抛物线转向指标（Parabolic SAR）的移动止损     |
//| 核心功能：继承自 CExpertTrailing，通过跟踪 Parabolic SAR 指标值，   |
//|           动态调整止损位，利用SAR"跟随价格加速移动"的特性，          |
//|           在趋势中锁定利润，同时在趋势反转时及时离场               |
//| 核心逻辑：SAR 指标在价格上方（空头）或下方（多头）生成点，随趋势发展逐渐靠近价格， |
//|           多单止损=SAR值（随价格上涨而上移），空单止损=SAR值（随价格下跌而下移） |
//+------------------------------------------------------------------+
class CTrailingPSAR : public CExpertTrailing
  {
protected:
   // 核心组件与参数（保护成员，子类可访问）
   CiSAR             m_sar;            // Parabolic SAR 指标对象（封装指标计算与数据读取）
   // SAR 指标可调参数（控制指标灵敏度与趋势跟踪特性）
   double            m_step;           // 步长（加速因子增量，默认0.02，值越大SAR跟随越快）
   double            m_maximum;        // 最大值（加速因子上限，默认0.2，限制SAR最大敏感度）

public:
   //----------------------------------------------------------------
   // 构造与析构函数
   //----------------------------------------------------------------
   /**
    * @brief 构造函数：初始化基于 SAR 的移动止损
    * @details 1. 初始化 SAR 指标对象及默认参数（步长=0.02，最大值=0.2，经典配置）；
    *          2. 继承父类 CExpertTrailing 的移动止损框架初始化
    */
                     CTrailingPSAR(void);

   /**
    * @brief 析构函数：清理基于 SAR 的移动止损资源
    * @details 释放 SAR 指标对象占用的内存，依赖父类析构逻辑完成止损框架资源清理
    */
                    ~CTrailingPSAR(void);

   //----------------------------------------------------------------
   // SAR 指标参数配置：修改指标核心参数（外部调用接口）
   //----------------------------------------------------------------
   /**
    * @brief 设置 SAR 步长（加速因子增量）
    * @param step [in] 步长值（建议0.01-0.1，值越大 SAR 随价格移动的速度越快，灵敏度越高）
    */
   void              Step(double step);

   /**
    * @brief 设置 SAR 最大值（加速因子上限）
    * @param maximum [in] 最大值（建议0.1-0.5，限制加速因子增长，避免 SAR 过于敏感）
    */
   void              Maximum(double maximum);

   //----------------------------------------------------------------
   // 指标初始化：创建并注册 SAR 指标（移动止损生效前提）
   //----------------------------------------------------------------
   /**
    * @brief 初始化 SAR 指标及相关数据
    * @param indicators [in] 指标集合对象（用于管理所有策略用到的指标）
    * @return bool - 初始化结果：true=成功（SAR 创建+注册到指标集合），false=失败
    * @note 调用流程：
    *       1. 检查指标集合指针有效性；
    *       2. 将 SAR 指标对象（m_sar）添加到指标集合；
    *       3. 调用 m_sar.Create() 绑定当前品种、周期及 SAR 参数（步长、最大值）；
    *       4. 若添加或创建失败，输出错误日志并返回 false
    */
   virtual bool      InitIndicators(CIndicators *indicators);

   //----------------------------------------------------------------
   // 移动止损核心逻辑：分别处理多单和空单的止损调整
   //----------------------------------------------------------------
   /**
    * @brief 检查多单（买入）的移动止损条件，计算新止损位
    * @param position [in] 持仓信息对象（包含开仓价、当前止损等数据）
    * @param sl [out] 新止损价（若满足条件则更新，否则为EMPTY_VALUE）
    * @param tp [out] 新止盈价（固定为EMPTY_VALUE，本类不调整止盈）
    * @return bool - 调整结果：true=已更新止损，false=未调整
    * @note 多单逻辑（利用 SAR 跟踪上升趋势）：
    *       1. 安全阈值=当前卖价（Bid）- 平台最小止损点数×点值（避免止损过近触发）；
    *       2. 新止损价=前一根K线的 SAR 值（m_sar.Main(1)），经价格精度标准化；
    *       3. 基准价=初始止损价（若未设置则用开仓价）；
    *       4. 触发条件：新止损价>基准价（确保止损上移）且新止损价<安全阈值（符合平台规则）；
    *       5. 满足条件则更新止损为 SAR 值，随 SAR 上移自动提高，锁定下方利润
    */
   virtual bool      CheckTrailingStopLong(CPositionInfo *position,double &sl,double &tp);

   /**
    * @brief 检查空单（卖出）的移动止损条件，计算新止损位
    * @param position [in] 持仓信息对象（包含开仓价、当前止损等数据）
    * @param sl [out] 新止损价（若满足条件则更新，否则为EMPTY_VALUE）
    * @param tp [out] 新止盈价（固定为EMPTY_VALUE，本类不调整止盈）
    * @return bool - 调整结果：true=已更新止损，false=未调整
    * @note 空单逻辑（利用 SAR 跟踪下降趋势）：
    *       1. 安全阈值=当前买价（Ask）+ 平台最小止损点数×点值（避免止损过近触发）；
    *       2. 新止损价=前一根K线的 SAR 值 + 点差×点值（补偿点差影响），经价格精度标准化；
    *       3. 基准价=初始止损价（若未设置则用开仓价）；
    *       4. 触发条件：新止损价<基准价（确保止损下移）且新止损价>安全阈值（符合平台规则）；
    *       5. 满足条件则更新止损为 SAR 值，随 SAR 下移自动降低，锁定上方利润
    */
   virtual bool      CheckTrailingStopShort(CPositionInfo *position,double &sl,double &tp);
  };
//+------------------------------------------------------------------+